﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;

namespace SerialPortHelper.utils
{
    static public class CodeUtils
    {
        /// <summary>
        /// 将字节数组转换为十六进制字符串表示
        /// </summary>
        /// <param name="bytes">待转换的字节数组</param>
        /// <param name="separator">分隔符，默认为空</param>
        /// <param name="upperCase">是否使用大写，默认为true</param>
        /// <returns>十六进制字符串，输入为null时返回空字符串</returns>
        public static string BytesToHexString(byte[] bytes, string separator = "", bool upperCase = true)
        {
            if (bytes == null || bytes.Length == 0)
                return string.Empty;
            string format = upperCase ? "X2" : "x2";
            // Select 是 LINQ 语法，对 bytes 中的每个字节均执行一边 lambda 中的方法后返回的新的序列
            return string.Join(separator, bytes.Select(b => b.ToString(format)));
        }


        /// <summary>
        /// 检查字符串是否仅包含十六进制字符（0-9, A-F, a-f），允许空字符串或null
        /// </summary>
        /// <param name="input">待检查的字符串</param>
        /// <param name="allowSpaces">是否允许包含空格</param>
        /// <returns>如果字符串有效则返回true，否则返回false</returns>
        public static bool IsHexString(string input, bool allowSpaces = false)
        {
            // 空字符串或null视为合法
            if (string.IsNullOrEmpty(input))
                return true;

            string validChars = "0123456789ABCDEFabcdef";
            if (allowSpaces)
                validChars += ' ';

            // 验证所有字符都是合法的十六进制字符或空格
            foreach (char c in input)
            {
                if (validChars.IndexOf(c) == -1)
                    return false; // 包含非法字符
            }
            
            // 移除空格并检查长度
            string cleanInput = input.Replace(" ", "");
            return cleanInput.Length > 0; // 只要不包含非法字符，即为有效
        }

        /// <summary>
        /// 将十六进制字符串转换为对应的字节数组，自动处理奇数长度的情况
        /// </summary>
        /// <param name="hex">十六进制字符串（允许空格，会自动忽略）</param>
        /// <returns>转换后的字节数组，或空数组（输入无效时）</returns>
        public static byte[] HexStrToByteArr(String hex)
        {
            if (string.IsNullOrEmpty(hex))
                return Array.Empty<byte>();

            // 移除空格并转换为大写
            string cleanHex = hex.Replace(" ", "").ToUpperInvariant();

            // 处理奇数长度的情况：在最后一个字符前补零
            if (cleanHex.Length % 2 != 0)
            {
                cleanHex = cleanHex.Insert(cleanHex.Length - 1, "0");
            }

            // 验证是否为合法的十六进制字符串
            if (!IsValidHex(cleanHex))
                return Array.Empty<byte>();

            // 转换为字节数组
            byte[] result = new byte[cleanHex.Length / 2];
            for (int i = 0; i < result.Length; i++)
            {
                result[i] = Convert.ToByte(cleanHex.Substring(i * 2, 2), 16);
            }
            return result;
        }

        // 辅助方法：验证字符串是否只包含合法的十六进制字符
        private static bool IsValidHex(string s)
        {
            foreach (char c in s)
            {
                if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')))
                    return false;
            }
            return true;
        }
    }
}
